package models

import (
	"encoding/xml"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

type Gateway struct {
	Name     string
	Username string
	Password string
	Realm    string
}

func GetAllGateways() []Gateway {
	var v GatewayVisitor

	filepath.Walk(getGatewayConfDir(),
		func(path string, f os.FileInfo, err error) error {
			v.visit(path, f, err)
			return nil
		})
	return v.gateways
}

func IsGatewayExist(name string) bool {
	var path string = getGatewayConfDir() + "/" + name + ".xml"
	if _, err := os.Stat(path); err == nil {
		return true
	}
	return false
}

func AddGateway(name string, accountcode string, password string, realm string) error {
	var path string = getGatewayConfDir() + "/" + name + ".xml"
	var include GatewayInclude
	include.Gateway.Name = name

	include.Gateway.Params = make([]Param, 0)
	include.Gateway.Params = append(include.Gateway.Params,
		Param{"username", accountcode})
	include.Gateway.Params = append(include.Gateway.Params,
		Param{"password", password})
	include.Gateway.Params = append(include.Gateway.Params,
		Param{"realm", realm})

	data, err := xml.MarshalIndent(&include, "", "  ")
	if err != nil {
		return err
	}

	var f *os.File
	f, err = os.Create(path)
	if err != nil {
		fmt.Println(err.Error())
		return err
	}
	io.WriteString(f, string(data))
	f.Close()

	return nil
}

func DelGateway(name string) error {
	var path string = getGatewayConfDir() + "/" + name + ".xml"

	err := os.Remove(path)
	if err != nil {
		fmt.Println(err.Error())
	}

	return nil
}

func getGatewayConfDir() string {
	return filepath.Join(getFSConfDir(), "sip_profiles/external")
}

type GatewayVisitor struct {
	gateways []Gateway
}

func (v *GatewayVisitor) visit(path string, f os.FileInfo, err error) error {
	if f.IsDir() {
		return nil
	}
	if isGatewayConfFile(path) {
		var gateway *Gateway
		gateway = getGatewayFromFile(path)
		if gateway != nil {
			v.gateways = append(v.gateways, *gateway)
		}

	}

	return nil
}

func isGatewayConfFile(path string) bool {
	if path != "" {
		if !strings.HasSuffix(path, "example.xml") {
			return true
		}
	}
	return false
}

func getGatewayFromFile(path string) *Gateway {
	content, err := ioutil.ReadFile(path)
	if err != nil {
		return nil
	}

	include := GatewayInclude{}
	err = xml.Unmarshal(content, &include)
	if err != nil {
		return nil
	}

	gatewayInfo := include.Gateway
	var gateway Gateway
	gateway.Name = gatewayInfo.Name
	for _, param := range gatewayInfo.Params {
		if param.Name == "username" {
			gateway.Username = param.Value
		}
		if param.Name == "password" {
			gateway.Password = param.Value
		}
		if param.Name == "realm" {
			gateway.Realm = param.Value
		}
	}

	return &gateway
}

type GatewayInclude struct {
	XMLName xml.Name     `xml:"include"`
	Gateway GatewayParam `xml:"gateway"`
}

type GatewayParam struct {
	Name   string  `xml:"name,attr"`
	Params []Param `xml:"param"`
}
